package com.zxd.interview.mycache.version5;

import com.zxd.interview.mycache.version4.MyCacheVersion4;

import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 可能失败的计算导致缓存污染问题处理
 * 1. 解决缓存污染问题。
 * 2. 异常情况尝试一直重复计算。
 *
 * @author Xander
 * @version v1.0.0
 * @Package : com.zxd.interview.mycache.version5
 * @Description :
 * @Create on : 2023/6/19 10:49
 **/
public class Test {

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        MyCacheVersion5<String, Integer> myCacheVersion5 = new MyCacheVersion5<>();
        Random random = new Random(100);
        for (int i = 0; i < 1000; i++) {
            executorService.submit(() -> {
                int randomInt = random.nextInt(100);

                Integer user = myCacheVersion5.compute(String.valueOf(randomInt));
                System.out.println("result => " + user);


            });
        }
        executorService.shutdown();
    }/**
     运行结果：
     短期内会有海量异常，这不符合预期情况。根本原因是缓存不存在过期时间，会存在无效的内容缓存计算

     其他线程进行设置,重新执行计算
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     java.util.concurrent.ExecutionException: java.lang.Exception: 自定义异常
     at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
     at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5.compute(MyCacheVersion5.java:63)
     at interview/com.zxd.interview.mycache.version5.Test.lambda$main$0(Test.java:30)
     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
     at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
     at java.base/java.lang.Thread.run(Thread.java:829)
     Caused by: java.lang.Exception: 自定义异常
     at interview/com.zxd.interview.mycache.compute.MayFailCompute.doCompute(MayFailCompute.java:37)
     at interview/com.zxd.interview.mycache.compute.MayFailCompute.doCompute(MayFailCompute.java:14)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5$1.call(MyCacheVersion5.java:47)
     at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5.compute(MyCacheVersion5.java:53)
     ... 7 more
     java.util.concurrent.ExecutionException: java.lang.Exception: 自定义异常
     at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
     at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5.compute(MyCacheVersion5.java:63)
     at interview/com.zxd.interview.mycache.version5.Test.lambda$main$0(Test.java:30)
     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
     at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
     at java.base/java.lang.Thread.run(Thread.java:829)
     Caused by: java.lang.Exception: 自定义异常
     at interview/com.zxd.interview.mycache.compute.MayFailCompute.doCompute(MayFailCompute.java:37)
     at interview/com.zxd.interview.mycache.compute.MayFailCompute.doCompute(MayFailCompute.java:14)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5$1.call(MyCacheVersion5.java:47)
     at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5.compute(MyCacheVersion5.java:53)
     ... 7 more
     java.util.concurrent.ExecutionException: java.lang.Exception: 自定义异常
     at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
     at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5.compute(MyCacheVersion5.java:63)
     at interview/com.zxd.interview.mycache.version5.Test.lambda$main$0(Test.java:30)
     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
     at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
     at java.base/java.lang.Thread.run(Thread.java:829)
     Caused by: java.lang.Exception: 自定义异常
     at interview/com.zxd.interview.mycache.compute.MayFailCompute.doCompute(MayFailCompute.java:37)
     at interview/com.zxd.interview.mycache.compute.MayFailCompute.doCompute(MayFailCompute.java:14)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5$1.call(MyCacheVersion5.java:47)
     at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
     at interview/com.zxd.interview.mycache.version5.MyCacheVersion5.compute(MyCacheVersion5.java:53)
     ... 7 more

     经过修复之后：
     16:09:07.705 [pool-1-thread-83] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 9，重新计算
     FutureTask 调用计算函数
     result => 37
     16:09:07.705 [pool-1-thread-84] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 84，重新计算
     16:09:07.705 [pool-1-thread-66] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 84，重新计算
     FutureTask 调用计算函数
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     16:09:07.705 [pool-1-thread-91] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 9，重新计算
     16:09:07.706 [pool-1-thread-2] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 84，重新计算
     16:09:07.706 [pool-1-thread-3] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 40，重新计算
     16:09:07.706 [pool-1-thread-5] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 84，重新计算
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     16:09:07.706 [pool-1-thread-91] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 9，重新计算
     其他线程进行设置,重新执行计算
     16:09:07.706 [pool-1-thread-3] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 40，重新计算
     16:09:07.706 [pool-1-thread-5] INFO com.zxd.interview.mycache.version5.MyCacheVersion5 - 移除缓存Key => 84，重新计算
     FutureTask 调用计算函数
     FutureTask 调用计算函数
     其他线程进行设置,重新执行计算
     FutureTask 调用计算函数
     FutureTask 调用计算函数
     */
}
